package com.beauty.product.controller;

import com.beauty.product.dto.PageResponse;
import com.beauty.product.dto.ProductAttributeDto;
import com.beauty.product.dto.ProductDto;
import com.beauty.product.dto.ProductImageDto;
import com.beauty.product.dto.ProductQueryParam;
import com.beauty.product.result.Result;
import com.beauty.product.service.ProductService;
import com.beauty.product.service.ProductElasticsearchService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/product")
@RequiredArgsConstructor
@Slf4j
public class ProductController {

    private final ProductService productService;
    private final ProductElasticsearchService productElasticsearchService;

    @PostMapping
    public Result<ProductDto> createProduct(@Valid @RequestBody ProductDto productDto) {
        return Result.success(productService.createProduct(productDto));
    }

    @GetMapping("/{id}")
    public Result<ProductDto> getProduct(@PathVariable String id) {
        return Result.success(productService.getProductById(id));
    }

    @GetMapping("/sku/{sku}")
    public Result<ProductDto> getProductBySku(@PathVariable String sku) {
        return Result.success(productService.getProductBySku(sku));
    }

    @GetMapping("/search")
    public Result<Page<ProductDto>> searchProducts(ProductQueryParam param) {
        return Result.success(productService.getProducts(param));
    }

    @GetMapping("/category/{categoryId}")
    public Result<Page<ProductDto>> getProductsByCategory(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        return Result.success(productService.getProductsByCategory(categoryId, pageNum, pageSize));
    }

    @GetMapping("/hot")
    public Result<List<ProductDto>> getHotProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getHotProducts(limit));
    }

    @GetMapping("/new")
    public Result<List<ProductDto>> getNewProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getNewProducts(limit));
    }

    @GetMapping("/recommended")
    public Result<List<ProductDto>> getRecommendedProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getRecommendedProducts(limit));
    }

    @PutMapping("/{id}")
    public Result<ProductDto> updateProduct(
            @PathVariable String id,
            @Valid @RequestBody ProductDto productDto) {
        return Result.success(productService.updateProduct(id, productDto));
    }

    @DeleteMapping("/{id}")
    public Result<Void> deleteProduct(@PathVariable String id) {
        productService.deleteProduct(id);
        return Result.success();
    }

    @PutMapping("/{id}/publish")
    public Result<Void> publishProduct(
            @PathVariable String id,
            @RequestParam Boolean isPublished) {
        productService.publishProduct(id, isPublished);
        return Result.success();
    }

    @PostMapping("/{productId}/images")
    public Result<ProductImageDto> addProductImage(
            @PathVariable String productId,
            @Valid @RequestBody ProductImageDto imageDto) {
        return Result.success(productService.addProductImage(productId, imageDto));
    }

    @GetMapping("/{productId}/images")
    public Result<List<ProductImageDto>> getProductImages(@PathVariable String productId) {
        return Result.success(productService.getProductImages(productId));
    }

    @DeleteMapping("/images/{imageId}")
    public Result<Void> deleteProductImage(@PathVariable Long imageId) {
        productService.deleteProductImage(imageId);
        return Result.success();
    }

    @PostMapping("/{productId}/attributes")
    public Result<ProductAttributeDto> addProductAttribute(
            @PathVariable String productId,
            @Valid @RequestBody ProductAttributeDto attributeDto) {
        return Result.success(productService.addProductAttribute(productId, attributeDto));
    }

    @GetMapping("/{productId}/attributes")
    public Result<List<ProductAttributeDto>> getProductAttributes(@PathVariable String productId) {
        return Result.success(productService.getProductAttributes(productId));
    }

    @DeleteMapping("/attributes/{attributeId}")
    public Result<Void> deleteProductAttribute(@PathVariable Long attributeId) {
        productService.deleteProductAttribute(attributeId);
        return Result.success();
    }

    @GetMapping("/page")
    public Result<PageResponse<ProductDto>> getProductsPage(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到获取商品分页请求: page={}, size={}, sort={}, direction={}", page, size, sort, direction);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.getProductsPage(pageable);
        return Result.success(response);
    }

    @GetMapping("/search/quick")
    public Result<PageResponse<ProductDto>> searchProducts(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到模糊查询请求: keyword={}, page={}, size={}", keyword, page, size);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.searchProducts(keyword, pageable);
        return Result.success(response);
    }

    @GetMapping("/search/advanced")
    public Result<PageResponse<ProductDto>> advancedSearch(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String sku,
            @RequestParam(required = false) String brand,
            @RequestParam(required = false) String description,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到高级搜索请求，参数: 商品名称={}, SKU={}, 品牌={}, 页码={}, 每页数量={}",
                name, sku, brand, page, size);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.advancedSearch(
                name, sku, brand, description, pageable);
        return Result.success(response);
    }

    @PostMapping("/sync/elasticsearch")
    public Result<String> syncElasticsearch() {
        productElasticsearchService.syncAllProductsFromDB();
        return Result.success("所有产品已同步到Elasticsearch");
    }

    @GetMapping("/es/search")
    public ResponseEntity<PageResponse<ProductDto>> searchByES(
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        Pageable pageable = PageRequest.of(page, size);
        PageResponse<ProductDto> response = productElasticsearchService.search(keyword, pageable);
        return ResponseEntity.ok(response);
    }
}
